DEFINE_BASECLASS( "gamemode_base" )

--[[========================================================
	INCLUDES
========================================================]]--
include( "class.lua" )
include( "helpers/sanity_checks.lua" )
include( "helpers/date_time.lua" )
include( "helpers/math_helper.lua" )
include( "helpers/color_helper.lua" )
include( "helpers/useful.lua" )
include( "debug/debug.lua" )
include( "helpers/net_helper.lua" )
include( "timer.lua" )
include( "classes/field_info.lua" )
include( "classes/sound_info.lua" )
include( "classes/activity_info.lua" )
include( "classes/damage_info.lua" )
include( "classes/view_transform_info.lua" )
include( "classes/object_type.lua" )
include( "classes/weapon.lua" )
include( "classes/firemode.lua" )
include( "classes/weapon_firemode.lua" )
include( "config/config.lua" )
include( "input/input.lua" )
include( "extensions/player_extension.lua" )
include( "vehicles/test_drive.lua" )
include( "classes/test_classes.lua" )

--[[========================================================
	GAMEMODE CONFIGURATION
========================================================]]--

--[[----------------------------------------------------]]--
--[[	Information										]]--
--[[----------------------------------------------------]]--
GM.Name					= "Sigma.Core"
GM.Author				= "McFly"
GM.Email				= ""
GM.Website				= "http://www.voxelzero.net"
GM.ThisClass			= "gamemode_sigmacore"

--[[========================================================
	GAMEMODE EVENTS
========================================================]]--

GM.LAST_KEYS			= {}

if SERVER then

--[[----------------------------------------------------]]--
--[[	First time player spawns						]]--
--[[----------------------------------------------------]]--
function GM:PlayerInitialSpawn( ply )

	--	Set default view
	ply.FirstPerson		= not tobool( GetConVarNumber( "sc_allow_third_person" ) )

	--	Initialize double-key elements at player's first spawn
	sc_input.InitializePlayerInput( ply )

end

end

--[[----------------------------------------------------]]--
--[[	Prepare network variables						]]--
--[[----------------------------------------------------]]--
function GM:SetupDataTables()
	
	--	DT variables
	self:DTVar( "Bool", 1, "ironsights" )
	self:DTVar( "Bool", 2, "shooting" )
end

--[[----------------------------------------------------]]--
--[[	Player has been fully authenticated				]]--
--[[----------------------------------------------------]]--
function GM:PlayerAuthed( ply, steamID, uniqueID )

	RegisterPlayer( ply:EntIndex() )

end

--[[----------------------------------------------------]]--
--[[	Player pressed a key							]]--
--[[----------------------------------------------------]]--
function GM:KeyPress( ply, key )
	
	-- if ply.Vehicle and ply.Vehicle:IsValid() then
		-- ply.Vehicle:KeyPress(pl, key)
		-- return
	-- end

	--	Smoothly change FOV if player is holding right mouse
	if key == IN_ATTACK2 and tobool( GetConVarNumber( "sc_allow_zoom" ) ) then
		ply:SetFOV( 40, 0.4 )
	end
	
	--	Vehicle test
	if SERVER and key == IN_SCORE then 
	
		if not ply.Vehicle then
			local vehicle	= ents.Create( "prop_physics" )
			vehicle:SetModel("models/props_vehicles/car002a_physics.mdl")
			vehicle:SetPos( ply:GetPos() + ply:GetAimVector() * 300 )
			vehicle:PhysicsInitBox(Vector(-75.5, -37, -24) * 1, Vector(75.5, 37, 32) * 1)
			vehicle:SetCollisionBounds(Vector(-75.5, -37, -24) * 1, Vector(75.5, 37, 32) * 1)
			vehicle:SetSolid( SOLID_VPHYSICS )
			vehicle:SetPos( ply:GetPos() )
			vehicle:SetAngles( ply:EyeAngles() )

			local phys = vehicle:GetPhysicsObject()
			if phys:IsValid() then
				phys:SetMaterial("metal")
				phys:SetMass(750)
				phys:SetBuoyancyRatio(14)
				phys:SetDamping(0.1 * 1, 2)
				phys:EnableMotion(true)
				phys:EnableDrag(false)
				phys:Wake()
			end
			
			vehicle:Spawn()
			vehicle:Activate()
			drive.PlayerStartDriving( ply, vehicle, "test_drive" )
			--ply:Spectate( OBS_MODE_CHASE )
			--ply:SpectateEntity( vehicle )
			ply:SetParent( vehicle )
			ply.Vehicle 	= vehicle
		else
			drive.PlayerStopDriving( ply )
			--ply:UnSpectate()
			ply:SetParent( nil )
			ply.Vehicle:Remove()
			ply.Vehicle 	= nil
		end
	end
	
	--	Change walk speed
	if key == IN_DUCK then
		ply:SetWalkSpeed( 75 )
	end
	
	--	Handle double-press
	sc_input.CheckDoubleKeyPress( ply, key )

end

--[[----------------------------------------------------]]--
--[[	Player released a key							]]--
--[[----------------------------------------------------]]--
function GM:KeyRelease( ply, key )

	--	Reset FOV
	if key == IN_ATTACK2 then
		ply:SetFOV( 0, 0.25 )
	end
	
	--	Reset run speed
	if key == IN_FORWARD or key == IN_SPEED then
		ply:SetRunSpeed( 175 )
	end
	
	--	Reset walk speed
	if key == IN_DUCK then
		ply:SetWalkSpeed( 100 )
	end

end

if SERVER then

--[[----------------------------------------------------]]--
--[[	Prepares a player								]]--
--[[----------------------------------------------------]]--
function RegisterPlayer( plyID )

	--	Retrieve the player
	local ply			= player.GetByID( plyID )
	
	--	Wait for player to be initialized
	if	( GAMEMODE:IsBase() and GAMEMODE.ServerCVars == nil ) or
		( not GAMEMODE:IsBase() and GAMEMODE.BaseClass.ServerCVars == nil ) then
		timer.Simple( 0.5, function() RegisterPlayer( ply:EntIndex() ) end )
		return
	end

	--	Load server CVars
	if GAMEMODE:IsBase() then
		for k,v in pairs( GAMEMODE.ServerCVars ) do
			GAMEMODE:NotifyPlayerServerVarChanged( ply, k, v.Prev, v.Next )
		end
	else
		for k,v in pairs( GAMEMODE.BaseClass.ServerCVars ) do
			GAMEMODE.BaseClass:NotifyPlayerServerVarChanged( ply, k, v.Prev, v.Next )
		end
	end
	
	--	Register
	ply.Registered		= true

end

end